/*
	This class implements a consumer. Each consumer thread is associated with a unique Consumer object.
*/
#ifndef CONSUMER_H_
#define CONSUMER_H_
#include "TaskContainer.h"
#include "Config.h"
#include <time.h>
#include <list>

class Consumer {
	TaskContainer* container;  // the container on which the consumer operates
	static bool stopFlag;  // a flag indicating all consumers should stop
	int numOfTasks;  //number of retrieved  tasks
	long maxWaitingTime;  // maximal time a task, retrieved by the consumer, was waiting in the container
	long waitingMeasurementsSum;  // total retrieval time (in ms) for all tasks with valid insertion time fields
	long waitingMeasurementsCount; // number of tasks retrieved that has valid insertion time fields
	double throughput;  // tasks retrieved per ms
	int exitsNum;  //number of times the consumer left its chip (work group)
	struct timespec* ts;  //for time measurements
	Statistics* stat;  //consumer's CAS statistics
	bool retrieveTask(); // returns true is retrieval was successful and false otherwise
public:
	/* consumer identifier (not pthread_t thread id). needs to be explicitly assigned by caller */
	int id; 
	
	Consumer();
	void setContainer(TaskContainer* container){this->container = container;}
	static void stop(){stopFlag = true;}
	void run();
	virtual ~Consumer();

	// getters
	double getThroughput(){return throughput;}
	Statistics* getStatistics(){return stat;}
	int getNumOfTasks(){return numOfTasks;}
	long getMaxWaitingTime(){return maxWaitingTime;}
	long getWaitingMeasurementsSum(){return waitingMeasurementsSum;}
	long getWaitingMeasurementsCount(){return waitingMeasurementsCount;}
	int getExitsNum(){return exitsNum;}
	
	/***** for debug only ***/
	//long longestWaitingTask[6];  // debug info about the longest waiting task retrieved by the consumer
	int debugInfo;
	/************************/
};

#endif /* CONSUMER_H_ */
